home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / xeno / bbbbscd.lha / BBBBScd / Xenolink / Utilities / junkmail.c < prev    next >
C/C++ Source or Header  |  1992-09-25  |  8KB  |  346 lines

  1. //
  2. // junkmail.c by Alan Bland  9/25/92
  3. //
  4. // Sample source file for sending mail from a shell command.
  5. //
  6. // Requirements:  SAS/C 5.10b, Xenolink Z.3a
  7. //
  8. // This source file is public domain and may be used for any purpose
  9. // without permission of the author.  The author claims no responsibility
  10. // for the consequences of using this program.
  11. //
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <sys/types.h>
  17. #include <sys/stat.h>
  18. #include <exec/types.h>
  19. #include <exec/ports.h>
  20. #include <exec/io.h>
  21. #include <exec/semaphores.h>
  22. #include <exec/libraries.h>
  23. #include <dos/dos.h>
  24. #include <proto/dos.h>
  25. #include <proto/exec.h>
  26. #include "xenolink.h"
  27.  
  28.  
  29. struct XenolinkBase  *XenolinkBase;
  30.  
  31. #define MAX_ATTACH 30
  32. #define MAX_RECIPIENTS 500
  33. char *j_from = NULL;
  34. char *j_to[MAX_RECIPIENTS];
  35. short j_next_recipient = 0;
  36. char *j_subject = NULL;
  37. char *j_input = NULL;
  38. char j_private = 0;
  39. char *j_attach[MAX_ATTACH];
  40. short j_next_attach = 0;
  41. short j_base = -1;
  42.  
  43. int CXBRK(void) { return 0; }
  44. int chkabort(void) { return 0; }
  45.  
  46. char *readinputfile(char *filename)
  47. {
  48.     char *text;
  49.     char *bp;
  50.     FILE *f;
  51.     struct stat st;
  52.  
  53.     // get file size and read in the file, converting \n to \r\n (hard newline)
  54.     if (stat(filename, &st) != 0) {
  55.         printf("File '%s' not found\n", filename);
  56.         return NULL;
  57.     }
  58.     // malloc an extra 4K to allow for \n to \r\n expansion
  59.     // SAS/C automatically frees this on exit
  60.     text = calloc(1, st.st_size + 4096);
  61.     if (!text) {
  62.         printf("Can't allocate %d bytes\n", st.st_size + 4096);
  63.         return NULL;
  64.     }
  65.  
  66.     f = fopen(filename, "r");
  67.     if (!f) {
  68.         printf("Can't open '%s'\n", filename);
  69.         return NULL;
  70.     }
  71.     bp = text;
  72.     while (fgets(bp, 1000, f)) {
  73.         // fgets ends with \n, find it and convert
  74.         while (*bp && *bp != '\n') ++bp;
  75.         if (*bp) {
  76.             *bp++ = '\r';
  77.             *bp++ = '\n';
  78.         }
  79.     }
  80.     fclose(f);
  81.     return text;
  82. }
  83.  
  84. //
  85. // This function does all the nitty-gritty stuff for sending a message.
  86. //
  87. void xeno_send(char *from, char *to, char *MessageText, char *subject, short base,
  88.       short private, char *attach[], short num_attach)
  89. {
  90.     struct Msg SaveMsg;
  91.     struct MsgSection *MsgSect;
  92.     struct ManagerSaveMsgCommand SaveCommand;
  93.     struct FidoNetAddress destination;
  94.     int i;
  95.  
  96.     /* Start with a clean slate. */
  97.     ulibClearMem((void *)&SaveMsg, sizeof(SaveMsg));
  98.  
  99.     MsgSect = ulibGetMsgSectionInfo(base);
  100.     if (!MsgSect) {
  101.         printf("Base %d is invalid\n", base);
  102.         return;
  103.     }
  104.  
  105.     SaveMsg.Section = base;
  106.     SaveMsg.Flags.Private = private;
  107.     strncpy(SaveMsg.Subject, subject, SUBJECT_LENGTH);
  108.     strncpy(SaveMsg.From, from, USERNAME_LENGTH);
  109.  
  110.     // copy recipient name, parsing out the netmail address if specified
  111.     ulibClearMem((void *)&destination, sizeof(destination));
  112.     for (i=0; i<USERNAME_LENGTH; ++i) {
  113.         if (to[i] == '@') {
  114.             destination.Zone = MsgSect->Zone;
  115.             if (ulibParseFidoNetAddress(&to[i+1], &destination)) {
  116.                 printf("Fidonet address is invalid\n");
  117.                 return;
  118.             }
  119.             SaveMsg.To[i] = 0;
  120.             break;
  121.         }
  122.         SaveMsg.To[i] = to[i];
  123.         if (!to[i]) break;
  124.     }
  125.  
  126.     /* Date sent */
  127.     ulibStoreTodaysDate(&SaveMsg.DateSent);
  128.  
  129.     /* Convert JONATHAN FORBES to Jonathan Forbes, etc. */
  130.     ulibNiceName(SaveMsg.To);
  131.     ulibNiceName(SaveMsg.From);
  132.  
  133.     /* Netmail stuff -- could change this to get aka address for Orig... */
  134.     SaveMsg.OrigZone  = MsgSect->Zone;
  135.     SaveMsg.OrigNet   = MsgSect->Net;
  136.     SaveMsg.OrigNode  = MsgSect->Node;
  137.     SaveMsg.OrigPoint = 0;
  138.     SaveMsg.DestZone  = destination.Zone;
  139.     SaveMsg.DestNet   = destination.Net;
  140.     SaveMsg.DestNode  = destination.Node;
  141.     SaveMsg.DestPoint = destination.Point;
  142.  
  143.     /* Better make sure destination address was given if this is netmail */
  144.     if (MsgSect->MsgSectionFlags.NetMail && destination.Zone == 0) {
  145.         printf("Destination address required for netmail section\n");
  146.         return;
  147.     }
  148.     
  149.     /* Clear this structure so that no flags or anything else are set */
  150.     ulibClearMem((void *) &SaveCommand, sizeof(struct ManagerSaveMsgCommand));
  151.  
  152.     SaveCommand.SaveMessage = &SaveMsg;
  153.     SaveCommand.Message     = (void *) MessageText;
  154.  
  155.     /* Construct Fidonet tag line */
  156.     SaveCommand.Flags.AppendOrigin = 1;
  157.     SaveCommand.Flags.CustomTagLine = 0;
  158.     SaveCommand.Flags.AddWaitingMessage = 1;
  159.     SaveCommand.Flags.AppendNetInfo = 1;
  160.     SaveCommand.SaveType = SAVETYPE_PROGRAM;
  161.  
  162.     /* If SaveCommand.TextLength equals zero, then MT will perform a    */
  163.     /* strlen() on your text to see how long it is.  If TextLength is   */
  164.     /* nonzero, then MT will use that value of TextLength as the length */
  165.     /* of the message text.  This is simply a minor optimisation if you */
  166.     /* happen to know the length of your message beforehand.            */
  167.     SaveCommand.TextLength       = 0;
  168.  
  169.     if (num_attach > 0) {
  170.         ulibSetMsgData(&SaveMsg, XMD_FLAGS_FILE_ATTACHED, 1);
  171.     }
  172.  
  173.     ulibSaveMessage(&SaveCommand);
  174.  
  175.     // NOTE: we do not update message counts written by the user!
  176.  
  177.     if (num_attach > 0) {
  178.         char attname[100];
  179.         FILE *wp;
  180.         sprintf(attname, "%s%d.%d.attach", MsgSect->MsgSecDir,
  181.             base, SaveMsg.Number);
  182.         wp = fopen(attname, "w");
  183.         if (wp) {
  184.             for (i=0; i<num_attach; ++i) {
  185.                 fprintf(wp, "%s\n", attach[i]);
  186.             }
  187.             fclose(wp);
  188.         }
  189.     }
  190.     printf("ok\n");
  191. }
  192.  
  193. void usage(void)
  194. {
  195.  printf("\nUsage: junkmail <options>\n\n"
  196.     "Required:\n"
  197.     "  -f user     Name of message author\n"
  198.     "  -t user     Name of message recipient (may be specified more than once)\n"
  199.     "              For netmail recipients, include netmail address as follows:\n"
  200.     "              -t \"The Cyborg@1:104/121.0\"  (all one quoted string)\n"
  201.     "  -s subject  Subject of message\n"
  202.     "  -i file     Input file containing message text\n"
  203.     "  -b number   Number of message base to deposit message\n"
  204.     "\nOptional:\n"
  205.     "  -p          Private (default is public)\n"
  206.     "  -a file     File to attach (may be specified more than once)\n"
  207.     "\n");
  208.  
  209.  exit(1);
  210. }
  211.  
  212. void checkarg(char *opt, char *arg)
  213. {
  214.     if (!arg || *arg == '-') {
  215.         printf("%s requires an argument\n", opt);
  216.         usage();
  217.     }
  218. }
  219.  
  220. void main(int argc, char *argv[])
  221. {
  222.     int i;
  223.     char *text;
  224.     
  225.     // Parse the command line by brute force.
  226.     for (i=1; i<argc; ++i) {
  227.         char *opt;
  228.         char *arg;
  229.  
  230.         opt = argv[i];
  231.         if (i < argc-1) {
  232.             arg = argv[i+1];
  233.         } else {
  234.             arg = NULL;
  235.         }
  236.  
  237.         if (strcmp(opt, "-f") == 0) {
  238.             checkarg(opt, arg);
  239.             if (j_from) {
  240.                 printf("Too many cooks!\n");
  241.                 usage();
  242.             }
  243.             j_from = arg;
  244.             ++i;
  245.         }
  246.         else if (strcmp(opt, "-t") == 0) {
  247.             checkarg(opt, arg);
  248.             if (j_next_recipient < MAX_RECIPIENTS) {
  249.                 j_to[j_next_recipient++] = arg;
  250.             } else {
  251.                 printf("Too many recipients!\n");
  252.                 usage();
  253.             }
  254.             ++i;
  255.         }
  256.         else if (strcmp(opt, "-s") == 0) {
  257.             checkarg(opt, arg);
  258.             if (j_subject) {
  259.                 printf("What's the real subject?\n");
  260.                 usage();
  261.             }
  262.             j_subject = arg;
  263.             ++i;
  264.         }
  265.         else if (strcmp(opt, "-p") == 0) {
  266.             j_private = 1;
  267.         }
  268.         else if (strcmp(opt, "-a") == 0) {
  269.             FILE *f;
  270.             checkarg(opt, arg);
  271.             f = fopen(arg, "r");
  272.             if (!f) {
  273.                 printf("Cannot attach '%s'\n", arg);
  274.                 usage();
  275.             }
  276.             fclose(f);
  277.             if (j_next_attach < MAX_ATTACH) {
  278.                 j_attach[j_next_attach++] = arg;
  279.             } else {
  280.                 printf("Too many file attaches!\n");
  281.                 usage();
  282.             }
  283.             ++i;
  284.         }
  285.         else if (strcmp(opt, "-i") == 0) {
  286.             checkarg(opt, arg);
  287.             if (j_input) {
  288.                 printf("Only one input file, please!\n");
  289.                 usage();
  290.             }
  291.             j_input = arg;
  292.             ++i;
  293.         }
  294.         else if (strcmp(opt, "-b") == 0) {
  295.             checkarg(opt, arg);
  296.             if (j_base >= 0) {
  297.                 printf("Only one message base, please!\n");
  298.                 usage();
  299.             }
  300.             j_base = atoi(arg);
  301.             ++i;
  302.         }
  303.         else {
  304.             printf("Unrecognized option: %s\n", opt);
  305.             usage();
  306.         }
  307.     }
  308.  
  309.     if (!j_from || j_next_recipient < 1 || !j_subject || !j_input || j_base < 0) {
  310.         usage();
  311.     }
  312.  
  313.     if ((text = readinputfile(j_input)) == NULL) {
  314.         usage();
  315.     }
  316.  
  317.     XenolinkBase = (struct XenolinkBase *) OpenLibrary("xenolink.library", 0);
  318.     if (!XenolinkBase) {
  319.         printf("Where's xenolink.library?\n");
  320.         exit(1);
  321.     }
  322.  
  323.  
  324. #if DEBUG
  325. printf("Base: %d\n", j_base);
  326. printf("%s\n", j_private ? "Private" : "Public");
  327. printf("From: %s\n", j_from);
  328. for (i=0; i<j_next_recipient; ++i) printf("  To: %s\n", j_to[i]);
  329. printf("Subj: %s\n", j_subject);
  330. for (i=0; i<j_next_attach; ++i) printf(" Att: %s\n", j_attach[i]);
  331. #endif
  332.  
  333.  
  334.     // Send the message to each recipient.
  335.     for (i=0; i<j_next_recipient; ++i) {
  336.         printf("Sending to %s...", j_to[i]);
  337.         xeno_send(j_from, j_to[i], text, j_subject, j_base, j_private,
  338.               j_attach, j_next_attach);
  339.     }
  340.  
  341.     CloseLibrary((struct Library *) XenolinkBase);
  342.     exit(0);
  343. }
  344.  
  345.  
  346.